package com.woniu108.person.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu108.carService.commons.log.AdminHistoryLog;
import com.woniu108.carService.commos.dto.AdminInfoDto;
import com.woniu108.carService.commos.dto.AdminSimpleDto;
import com.woniu108.carService.commos.exception.WoniuException;
import com.woniu108.carService.commos.model.Result;
import com.woniu108.carService.commos.util.*;
import com.woniu108.person.form.*;
import com.woniu108.person.model.AdminInfo;
import com.woniu108.person.param.*;
import com.woniu108.person.service.AdminInfoService;
import com.woniu108.person.service.AdminRoleService;
import com.woniu108.person.service.StoreService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 管理员信息表 前端控制器
 * </p>
 *
 * @author yanxi
 * @since 2024-05-23
 */

@RestController
@RequestMapping("/adminInfo")
@Api(tags = "管理员信息接口")
public class AdminInfoController {

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private OSSUtil ossUtil;

    public String getAdminId(String token){
        String refreshToken=redisUtil.getString(token);
        String adminId=JWTUtil.parseAdminToken(refreshToken).get("adminId").toString();
        return adminId;
    }


    @Resource
    private AdminInfoService adminInfoService;
    @Resource
    private AdminRoleService adminRoleService;
    @Resource
    private StoreService storeService;

    /**
     * 按form条件查找筛选所有管理员
     * adminInfoDto包含storeId和storeName,实际表内不包含门店管理员
     * @param form 姓名 手机号 门店ID 状态 权限 页码信息
     * @return page管理员dto对象  管理员ID 管理员权限编号 管理员权限名称 管理员手机号 管理员姓名 管理门店编号 门店名称 管理员状态ID
     */
    @PostMapping("/allAdmins.api")
    @ApiOperation("获取管理员信息列表")
    public Result<Page<AdminInfoDto>> allAdmins(@RequestBody FilterAdminForm form){
        FilterAdminParam param= BeanUtil.toBean(form,FilterAdminParam.class);
        Page<AdminInfoDto> page = adminInfoService.allAdmins(param);
        return Result.newPageInstance(AdminInfoDto.class).setData(page);
    }

    /**
     * 单一id查找管理员信息
     * @param adminId 管理员ID
     * @return 管理员dto对象  管理员ID 管理员权限编号 管理员权限名称 管理员手机号 管理员姓名 管理门店编号 门店名称 管理员状态ID
     */
    @GetMapping("/getByAdminId/{adminId}.api")
    @ApiOperation("单一id查找管理员信息")
    @ApiImplicitParam(name = "adminId",value ="管理员ID" )
    public Result<AdminInfoDto> getByAdminId(@PathVariable("adminId")String adminId){
        AdminInfo info = adminInfoService.getById(adminId);
        return Result.getResult(AdminInfoDto.class).setData(BeanUtil.toBean(info,AdminInfoDto.class));
    }

    /**
     * 删除普通管理员
     * @param token 管理员token
     * @param adminId 管理员ID
     * @return result 接口是否正常访问到结果
     */
    @GetMapping("/deleteAdmin.api")
    @ApiOperation("删除普通管理员")
    @ApiImplicitParam(name = "adminId",value ="管理员ID" )
    @AdminHistoryLog
    public Result deleteAdmin(@RequestHeader String token,String adminId){
        String currentId = this.getAdminId(token);
        if(ObjectUtil.isEmpty(currentId)) throw new WoniuException("非管理员账户",10001);
        if(adminId.equals(currentId)) throw new WoniuException("无法删除自己的管理员账号",10001);
        AdminInfo currentAdmin = adminInfoService.getById(currentId);
        AdminInfo admin = adminInfoService.getById(adminId);
        System.out.println("adminId:"+adminId);
        System.out.println(admin);
        System.out.println(currentAdmin);
        if(currentAdmin.getAdminRoleId()!=1||admin.getAdminRoleId()==1) throw new WoniuException("无权删除",10001);
        admin.setAdminState(StaticData.ADMIN_STATE_DELETE);
        adminInfoService.updateById(admin);
        return Result.getResult().setMsg("删除普通管理员成功");
    }

    /**
     * 新增普通管理员
     * @param token 管理员token
     * @param form 新增管理员输入的信息 姓名 手机号 编码管理 门店编号
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/addAdmin.api")
    @ApiOperation("新增普通管理员")
    @AdminHistoryLog
    public Result addAdmin(@RequestHeader String token,@RequestBody AddAdminForm form){
        String adminId = this.getAdminId(token);
        if(ObjectUtil.isEmpty(adminId)||adminInfoService.getById(adminId).getAdminRoleId()!=1) throw new WoniuException("非超级管理员,不可新增",10001);
        AddAdminParam param = BeanUtil.toBean(form, AddAdminParam.class);
        AdminInfo adminInfo = BeanUtil.toBean(param, AdminInfo.class);
        //(临时)判断新增的角色是否为客服，赋予固定adminId
        if(adminInfo.getAdminRoleId()==3){
            adminInfo.setAdminId("12391203934819287491341");
            adminInfo.setAdminRoleId(param.getAdminRoleId());
            adminInfo.setAdminState(StaticData.ADMIN_STATE_NORMAL);
            adminInfoService.updateById(adminInfo);
        }else{
            String random=new Snowflake(1,1).nextIdStr();
            if(param.getAdminPhone()!=null){
                QueryWrapper<AdminInfo> wrapper = new QueryWrapper<>();
                wrapper.eq("admin_phone",param.getAdminPhone());
                AdminInfo info = adminInfoService.getOne(wrapper);
                if(ObjectUtil.isNotEmpty(info)) throw new WoniuException("手机号码已注册",10001);
            }
            if(param.getAdminName()!=null){
                QueryWrapper<AdminInfo> wrapper = new QueryWrapper<>();
                wrapper.eq("admin_name",param.getAdminName());
                AdminInfo info = adminInfoService.getOne(wrapper);
                if(ObjectUtil.isNotEmpty(info)) throw new WoniuException("用户名已注册",10001);
            }
            adminInfo.setAdminId(random);
            adminInfo.setAdminRoleId(param.getAdminRoleId());
            adminInfo.setAdminState(StaticData.ADMIN_STATE_NORMAL);
            adminInfoService.save(adminInfo);
        }


        return Result.getResult().setMsg("添加管理员成功");
    }

    /**
     * 修改管理员信息,管理员权限仅超级管理员可修改
     * @param token 管理员token
     * @param form 需要修改的管理员信息 姓名 手机号 管理门店编号
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/changeAdmin.api")
    @ApiOperation("修改管理员信息")
    @AdminHistoryLog
    public Result changeAdmin(@RequestHeader String token,@RequestBody ChangeAdminForm form){
        String currentId = this.getAdminId(token);
        if(ObjectUtil.isEmpty(currentId)) throw new WoniuException("非管理员账户",10001);
        AdminInfo currentAdmin = adminInfoService.getById(currentId);
        ChangeAdminParam param=BeanUtil.toBean(form,ChangeAdminParam.class);
        String adminId = param.getAdminId();
        AdminInfo adminInfo = adminInfoService.getById(adminId);
        System.out.println(param);
        if(param.getAdminName()!=null) adminInfo.setAdminName(param.getAdminName());
        if(param.getAdminRoleId()!=null&&currentAdmin.getAdminRoleId()!=1) {
            throw new WoniuException("非超级管理员不可修改管理员权限",10001);
        }
        if(param.getAdminRoleId()!=null&&currentAdmin.getAdminRoleId()==1) adminInfo.setAdminRoleId(param.getAdminRoleId());
        if(param.getStoreId()!=null&&currentAdmin.getAdminRoleId()==1) adminInfo.setStoreId(param.getStoreId());
        if(param.getAdminPhone()!=null) adminInfo.setAdminPhone(param.getAdminPhone());
        adminInfoService.updateById(adminInfo);
        return Result.getResult().setMsg("修改管理员信息成功");
    }

    /**
     * 修改自身管理员信息
     *  @param adminName 需要修改的管理员信息 姓名
     * @return result 接口是否正常访问到结果
     */
    @GetMapping("/changeMyAdminInfo.api")
    @ApiOperation("修改自身的管理员信息")
    @AdminHistoryLog
    public Result changeMyAdminInfo(@RequestHeader String token,String adminName){
        String adminId = this.getAdminId(token);
        if(ObjectUtil.isEmpty(adminId)) throw new WoniuException("非管理员账户",10001);
        AdminInfo adminInfo = adminInfoService.getById(adminId);
        if(adminName==null) throw new WoniuException("无修改信息",10001);
        adminInfo.setAdminName(adminName);
        adminInfoService.updateById(adminInfo);
        return Result.getResult().setMsg("修改管理员信息成功");
    }


    /**
     * 修改密码
     * @param token 管理员token
     * @param form 两次旧密码 一次新密码
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/changeAdminPass.api")
    @ApiOperation("修改管理员密码")
    @AdminHistoryLog
    public Result changeAdminPass(@RequestHeader String token,@RequestBody ChangePassForm form){
        ChangePassParam param = BeanUtil.toBean(form, ChangePassParam.class);
        if(ObjectUtil.isEmpty(param.getOldPass())||ObjectUtil.isEmpty(param.getOldPassAgain())||ObjectUtil.isEmpty(param.getNewPass()))throw new WoniuException("信息不完整",10001);
        if(!param.getOldPass().equals(param.getOldPassAgain())) throw new WoniuException("两次旧密码不一致",10001);
        String adminId = this.getAdminId(token);
        AdminInfo adminInfo = adminInfoService.getById(adminId);
        adminInfo.setAdminPass(param.getNewPass());
        adminInfoService.updateById(adminInfo);
        return Result.getResult().setMsg("修改密码成功");
    }

    /**
     * 发送手机验证码
     * @param phone 手机号
     * @return result 接口是否正常访问到结果
     */
    @GetMapping("/sendCheckMessage")
    @ApiOperation("发送手机验证码")
    @ApiImplicitParam(name = "phone",value ="手机号码" )
    public Result sendCheckMessage(String phone){
        adminInfoService.sendCheckMessage(phone);
        return Result.getResult().setMsg("发送短信成功");
    }

    /**
     * 验证手机验证码
     * @param form 手机号 验证码
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/checkMessage")
    @ApiOperation("验证手机验证码")
    public Result checkMessage(@RequestBody CheckMessageForm form){
        CheckMessageParam param = BeanUtil.toBean(form, CheckMessageParam.class);
        adminInfoService.checkMessage(param);
        return Result.getResult().setMsg("验证码验证通过");
    }

    /**
     * 修改管理员手机号,前置/sendCheckMessage
     * @param token 管理员token
     * @param form 旧手机号码 验证码 新手机号码
     * @return result 接口是否正常访问到结果
     */
    @PostMapping("/changeAdminPhone.api")
    @ApiOperation("修改管理员手机号")
    @AdminHistoryLog
    public Result changeAdminPhone(@RequestHeader String token,@RequestBody ChangeAdminPhoneForm form){
        CheckMessageForm form1=new CheckMessageForm();
        form1.setCode(form.getCode());
        form1.setMobile(form.getAdminPhone());
        Result result = this.checkMessage(form1);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(), result.getCode());
        String adminId = this.getAdminId(token);
        String newPhone = form.getNewPhone();
        AdminInfo adminInfo = adminInfoService.getById(adminId);
        adminInfo.setAdminPhone(newPhone);
        adminInfoService.updateById(adminInfo);
        return Result.getResult().setMsg("修改管理员手机号成功");
    }

    /**
     * 管理员手机验证码登录
     * @param form 手机号 验证码
     * @param response
     * @return 管理员登录返回信息 手机号 姓名 权限名称
     */
    @PostMapping("/adminCodeLogin")
    @ApiOperation("管理员手机验证码登录")
    public Result<AdminSimpleDto> adminCodeLogin(@RequestBody AdminCodeLoginForm form, HttpServletResponse response){
        AdminCodeLoginParam param=BeanUtil.toBean(form,AdminCodeLoginParam.class);
        CheckMessageForm checkMessageForm = new CheckMessageForm();
        checkMessageForm.setMobile(param.getAdminPhone());
        checkMessageForm.setCode(param.getCode());
        Result result = this.checkMessage(checkMessageForm);
        if(result.getCode()!=200) throw new WoniuException(result.getMsg(),result.getCode());
        AdminSimpleDto dto=adminInfoService.adminCodeLogin(param.getAdminPhone());
        //更新双token
        Map<String, Object> map = BeanUtil.beanToMap(dto);
        HashMap<String,Object> accessBody=new HashMap<String,Object>();
        String random=new Snowflake(1,1).nextIdStr();
        accessBody.put("random",random);
        String accessToken= JWTUtil.createAdminToken(accessBody,60);//短token,有效时间60分钟
        String refreshToken=JWTUtil.createAdminToken(map,3*24*60);//长token，有效时间3天
        //保存长token到Redis
        redisUtil.setString(accessToken,refreshToken,3*24*60*60);
        //响应到前端,设置响应头,这里使用的是短token
        response.setHeader("token",accessToken);
        response.setHeader("Access-Control-Expose-Headers","token");
        return Result.getResult(AdminSimpleDto.class).setData(dto).setMsg("管理员登录成功");
    }

    /**
     * 管理员手机账号密码登录
     * @param form 手机号 密码
     * @param response
     * @return 管理员登录返回信息 手机号 姓名 权限名称
     */
    @PostMapping("/adminLogin")
    @ApiOperation("管理员手机账号密码登录")
    public Result<AdminSimpleDto> adminLogin(@RequestBody AdminLoginForm form,HttpServletResponse response){
       AdminLoginParam param = BeanUtil.toBean(form, AdminLoginParam.class);
       AdminSimpleDto dto=adminInfoService.adminLogin(param);
        //更新双token
        Map<String, Object> map = BeanUtil.beanToMap(dto);
        HashMap<String,Object> accessBody=new HashMap<String,Object>();
        String random=new Snowflake(1,1).nextIdStr();
        accessBody.put("random",random);
        String accessToken= JWTUtil.createAdminToken(accessBody,60);//短token,有效时间60分钟
        String refreshToken=JWTUtil.createAdminToken(map,3*24*60);//长token，有效时间3天
        //保存长token到Redis
        redisUtil.setString(accessToken,refreshToken,3*24*60*60);
        //响应到前端,设置响应头,这里使用的是短token
        response.setHeader("token",accessToken);
        response.setHeader("Access-Control-Expose-Headers","token");
       return Result.getResult(AdminSimpleDto.class).setMsg("管理员登录成功").setData(dto);
    }

    /**
     * 根据token获取当前管理员信息
     * @param token
     * @return AdminInfoDto 管理员详细信息
     */
    @GetMapping("/myAdminInfo.api")
    @ApiOperation("获取当前登录管理员信息")
    public Result<AdminInfoDto> myAdminInfo(@RequestHeader String token){
        String adminId = this.getAdminId(token);
        if(adminId==null) throw new WoniuException("管理员不存在",10001);
        AdminInfo adminInfo = adminInfoService.getById(adminId);
        if(adminInfo.getAdminState()!=StaticData.ADMIN_STATE_NORMAL) throw new WoniuException("管理员状态异常",10001);
        AdminInfoDto dto = BeanUtil.toBean(adminInfo, AdminInfoDto.class);
        dto.setAdminRoleName(adminRoleService.getById(dto.getAdminRoleId()).getAdminRoleName());
        if(dto.getStoreId()!=null){
            dto.setStoreName(storeService.getById(dto.getStoreId()).getStoreName());
        }
        return Result.getResult(AdminInfoDto.class).setData(dto);
    }
}

